import csv
import re
import tkinter as tk
from datetime import datetime
from tkinter import messagebox, scrolledtext, filedialog

import ttkbootstrap as tkb
from ttkbootstrap.constants import *

from app.util.annotation_util import annotate, ClassInfo
from app.view.base_view import View


@annotate(ClassInfo(name="MAC Generator", category="tool"))
class MacGeneratorView(View):
    """设置视图"""

    def __init__(self, parent, controller):
        super().__init__(parent, controller)
        # 默认起始MAC地址
        self.default_mac = "08-19-20-11-00-00"
        self.generated_macs = []

        # 构建UI
        self._create_widgets()

    def _create_widgets(self):
        # 标题
        title_label = tkb.Label(
            self,
            text="MAC地址生成工具",
            font=("Helvetica", 18, "bold")
        )
        title_label.pack(pady=(0, 20))

        # 输入区域框架
        input_frame = tkb.LabelFrame(self, text="设置", padding=15)
        input_frame.pack(fill=X, pady=(0, 15))

        # 起始MAC地址输入
        tkb.Label(input_frame, text="起始MAC地址:").grid(row=0, column=0, sticky=W, pady=5)

        self.mac_segments = []
        mac_frame = tkb.Frame(input_frame)
        mac_frame.grid(row=0, column=1, sticky=W, pady=5)

        # 分割符
        separators = ["-", "-", "-", "-", "-"]

        # 创建6个输入框用于MAC地址的6个部分
        for i in range(6):
            seg = tkb.Entry(mac_frame, width=3, font=("Monospace", 12))
            seg.grid(row=0, column=i * 2, padx=1)
            self.mac_segments.append(seg)

            # 添加分隔符（除了最后一个）
            if i < 5:
                sep_label = tkb.Label(mac_frame, text=separators[i])
                sep_label.grid(row=0, column=i * 2 + 1)

        # 设置默认MAC地址
        self.set_default_mac()

        # 生成数量输入
        tkb.Label(input_frame, text="生成数量:").grid(row=0, column=8, sticky=W, pady=5)
        self.count_var = tkb.IntVar(value=10)
        count_spinbox = tkb.Spinbox(
            input_frame,
            from_=1,
            to=1000,
            textvariable=self.count_var,
            width=10
        )
        count_spinbox.grid(row=0, column=9, sticky=W, pady=5)

        # 生成按钮
        generate_btn = tkb.Button(
            input_frame,
            text="生成MAC地址",
            command=self.generate_macs,
            bootstyle=SUCCESS
        )
        generate_btn.grid(row=0, column=10, padx=10, pady=5)

        # 格式选择框架
        format_frame = tkb.LabelFrame(self, text="输出格式", padding=15)
        format_frame.pack(fill=X, pady=(0, 15))

        self.format_var = tkb.StringVar(value="hyphen")

        # 三种格式选择
        hyphen_radio = tkb.Radiobutton(
            format_frame,
            text="08-19-20-11-00-00",
            variable=self.format_var,
            value="hyphen"
        )
        hyphen_radio.pack(side=LEFT, pady=2, padx=5)

        colon_radio = tkb.Radiobutton(
            format_frame,
            text="08:19:20:11:00:00",
            variable=self.format_var,
            value="colon"
        )
        colon_radio.pack(side=LEFT, pady=2, padx=5)

        none_radio = tkb.Radiobutton(
            format_frame,
            text="081920110000",
            variable=self.format_var,
            value="none"
        )
        none_radio.pack(side=LEFT, pady=2, padx=5)

        # 结果展示区域
        result_frame = tkb.LabelFrame(self, text="生成结果", padding=15)
        result_frame.pack(fill=BOTH, expand=YES, pady=(0, 15))

        # 结果文本框
        self.result_text = scrolledtext.ScrolledText(
            result_frame,
            wrap=tk.WORD,
            width=80,
            height=15,
            font=("Monospace", 10)
        )
        self.result_text.pack(fill=BOTH, expand=YES)

        # 操作按钮框架
        btn_frame = tkb.Frame(self)
        btn_frame.pack(fill=X, pady=(0, 10))

        # 复制按钮
        copy_btn = tkb.Button(
            btn_frame,
            text="复制结果",
            command=self.copy_results,
            bootstyle=PRIMARY
        )
        copy_btn.pack(side=LEFT, padx=5)

        # 清空按钮
        clear_btn = tkb.Button(
            btn_frame,
            text="清空结果",
            command=self.clear_results,
            bootstyle=WARNING
        )
        clear_btn.pack(side=LEFT, padx=5)

        # 重新生成按钮
        regenerate_btn = tkb.Button(
            btn_frame,
            text="重新生成",
            command=self.generate_macs,
            bootstyle=INFO
        )
        regenerate_btn.pack(side=LEFT, padx=5)

        # 保存按钮
        save_btn = tkb.Button(
            btn_frame,
            text="保存为CSV",
            command=self.save_to_csv,
            bootstyle=SUCCESS
        )
        save_btn.pack(side=RIGHT, padx=5)

        # 绑定输入验证
        for seg in self.mac_segments:
            seg.bind("<FocusOut>", self.validate_segment)
            seg.bind("<KeyRelease>", self.limit_input)

    def set_default_mac(self):
        """设置默认MAC地址"""
        default_segments = self.default_mac.split('-')
        for i, seg in enumerate(self.mac_segments):
            seg.delete(0, END)
            seg.insert(0, default_segments[i])

    def limit_input(self, event):
        """限制输入为两位十六进制字符"""
        entry = event.widget
        text = entry.get().upper()  # 转换为大写

        # 只保留十六进制字符
        filtered = re.sub(r'[^0-9A-F]', '', text)

        # 限制长度为2
        if len(filtered) > 2:
            filtered = filtered[:2]
        # 更新输入框
        entry.delete(0, END)
        entry.insert(0, filtered)

    def validate_segment(self, event):
        """验证MAC地址段是否有效"""
        entry = event.widget
        text = entry.get().upper()

        # 检查是否为有效的十六进制值
        if not re.match(r'^[0-9A-F]{2}$', text):
            entry.config(bootstyle=DANGER)
            return False
        else:
            entry.config(bootstyle=DEFAULT)
            return True

    def get_start_mac(self):
        """获取起始MAC地址的数值表示"""
        segments = [seg.get().upper() for seg in self.mac_segments]
        mac_str = ''.join(segments)
        return int(mac_str, 16)

    def format_mac(self, mac_int):
        """将整数形式的MAC地址转换为指定格式的字符串"""
        # 转换为12位十六进制字符串，不足的前面补0
        mac_hex = f"{mac_int:012X}"

        # 分割为6个部分
        segments = [mac_hex[i:i + 2] for i in range(0, 12, 2)]

        # 根据选择的格式进行拼接
        format_type = self.format_var.get()
        if format_type == "hyphen":
            return "-".join(segments)
        elif format_type == "colon":
            return ":".join(segments)
        else:  # none
            return "".join(segments)

    def generate_macs(self):
        """生成指定数量的MAC地址"""
        try:
            count = self.count_var.get()
            if count < 1 or count > 100000:
                messagebox.showerror("输入错误", "生成数量必须在1到100000之间")
                return

            start_mac = self.get_start_mac()
            self.generated_macs = []

            for i in range(count):
                current_mac = start_mac + i
                # 确保MAC地址不超过6字节
                if current_mac > 0xFFFFFFFFFFFF:
                    messagebox.showwarning("警告", "生成的MAC地址超出范围，已截断")
                    break

                self.generated_macs.append(self.format_mac(current_mac))

            # 显示生成的MAC地址
            self.result_text.delete(1.0, END)
            self.result_text.insert(END, "\n".join(self.generated_macs))

        except Exception as e:
            messagebox.showerror("错误", f"生成MAC地址时出错: {str(e)}")

    def copy_results(self):
        """复制结果到剪贴板"""
        if not self.generated_macs:
            messagebox.showinfo("提示", "没有可复制的MAC地址，请先生成")
            return

        self.clipboard_clear()
        self.clipboard_append("\n".join(self.generated_macs))
        messagebox.showinfo("成功", "MAC地址已复制到剪贴板")

    def clear_results(self):
        """清空结果区域"""
        self.result_text.delete(1.0, END)
        self.generated_macs = []

    def save_to_csv(self):
        """保存生成的MAC地址到CSV文件"""
        if not self.generated_macs:
            messagebox.showinfo("提示", "没有可保存的MAC地址，请先生成")
            return

        try:
            # 生成默认文件名
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            default_filename = f"mac_addresses_{timestamp}.csv"

            # 创建文件对话框
            file_path = filedialog.asksaveasfilename(
                defaultextension=".csv",
                filetypes=[("CSV文件", "*.csv"), ("所有文件", "*.*")],
                initialfile=default_filename
            )

            if not file_path:
                return  # 用户取消了保存

            # 保存为CSV
            with open(file_path, 'w', newline='', encoding='utf-8') as file:
                writer = csv.writer(file)
                writer.writerow(["MAC地址"])
                for mac in self.generated_macs:
                    writer.writerow([mac])

            messagebox.showinfo("成功", f"MAC地址已保存到:\n{file_path}")

        except Exception as e:
            messagebox.showerror("错误", f"保存文件时出错: {str(e)}")

    def create_widgets(self):
        pass
